Built-up Index · Composite Urban Indicator

IBI – Index-based Built-up Index

IBI is a composite urban index that integrates NDBI, NDVI, and MNDWI to enhance built-up areas while suppressing vegetation and water signals, making it powerful for urban mapping and expansion studies.

1. Scientific Definition

The Index-based Built-up Index (IBI) (Xu, 2008) combines three spectral indices: NDBI for built-up, NDVI for vegetation and MNDWI for water, into a single normalized index.

Component Indices

NDVI = (NIR − Red) / (NIR + Red)

MNDWI = (Green − SWIR) / (Green + SWIR)

NDBI = (SWIR − NIR) / (SWIR + NIR)

IBI Formula (Xu, 2008)

IBI = (NDBI − (NDVI + MNDWI)) / (NDBI + (NDVI + MNDWI)) Range: −1 → +1

Typical Interpretation

IBIMeaning
< 0Non-built-up: vegetation, water, bare soil
0 – 0.2Low-density / mixed built-up
0.2 – 0.4Moderate urban fabric / suburban
> 0.4Dense built-up / urban core

Main Applications

  • Urban growth and expansion mapping
  • Built-up vs non-built-up classification
  • Impervious surface and city density analysis
  • Integration with LULC and planning models

2. Data & Bands

Sentinel-2 (Recommended)

  • Blue: B2 (for visualization only if needed)
  • Green: B3
  • Red: B4
  • NIR: B8
  • SWIR (SWIR1): B11

Landsat 8 / 9 Equivalents

  • Green: B3
  • Red: B4
  • NIR: B5
  • SWIR1: B6

Best Practices

  • Use surface reflectance (SR) collections.
  • Mask clouds & cloud shadows using QA bands.
  • Use IBI together with NDBI/NDVI/MNDWI for more detailed urban analysis.
  • Apply thresholds or clustering (e.g., Otsu, k-means) for built-up extraction.

Suggested Palette

[ "#08141f", "#1b2b3c", "#274764", "#3c6ea6", "#6baed6", "#dbeeff" ]

3. Google Earth Engine Code – IBI (Xu 2008)

// IBI (Index-based Built-up Index) using Sentinel-2 SR
// Xu (2008):
// NDVI  = (NIR - RED) / (NIR + RED)
// MNDWI = (GREEN - SWIR) / (GREEN + SWIR)
// NDBI  = (SWIR - NIR) / (SWIR + NIR)
// IBI   = (NDBI - (NDVI + MNDWI)) / (NDBI + (NDVI + MNDWI))

var roi = geometry;   // Draw AOI as 'geometry'
Map.centerObject(roi, 11);

// 1. Load Sentinel-2 SR
var s2 = ee.ImageCollection("COPERNICUS/S2_SR")
  .filterBounds(roi)
  .filterDate("2023-01-01", "2023-12-31")
  .filter(ee.Filter.lt("CLOUDY_PIXEL_PERCENTAGE", 20))
  .select(["B3","B4","B8","B11"]); // Green, Red, NIR, SWIR1

// 2. Median composite
var img = s2.median().clip(roi);

// 3. Compute NDVI, MNDWI, NDBI
var ndvi = img.normalizedDifference(["B8","B4"]).rename("NDVI");      // (NIR - Red)/(NIR + Red)
var mndwi = img.normalizedDifference(["B3","B11"]).rename("MNDWI");   // (Green - SWIR)/(Green + SWIR)
var ndbi = img.normalizedDifference(["B11","B8"]).rename("NDBI");     // (SWIR - NIR)/(SWIR + NIR)

// 4. Compute IBI using Xu (2008) formulation
var ibi = ee.Image().expression(
  "(NDBI - (NDVI + MNDWI)) / (NDBI + (NDVI + MNDWI))",
  {
    "NDBI": ndbi,
    "NDVI": ndvi,
    "MNDWI": mndwi
  }
).rename("IBI");

// 5. Visualization
var vis = {
  min: -1,
  max: 1,
  palette: ["#08141f","#1b2b3c","#274764","#3c6ea6","#6baed6","#dbeeff"]
};

Map.addLayer(ibi, vis, "IBI (Index-based Built-up Index)");

// Optional: threshold for built-up (e.g. IBI > 0)
var builtupMask = ibi.gt(0).selfMask();
Map.addLayer(builtupMask, {palette:["#ffcc00"]}, "Built-up Mask (IBI > 0)", false);

// 6. Export IBI as GeoTIFF
Export.image.toDrive({
  image: ibi,
  description: "IBI_Export",
  fileNamePrefix: "IBI_Xu2008",
  region: roi,
  scale: 20,        // SWIR band resolution
  crs: "EPSG:4326",
  maxPixels: 1e13
});